/**
 * This file is part of ossecdb-extjs.
 *
 * Copyright (C) 2011 Brendan Johnston
 *
 * Contact: brendan@johnston.net.au
 *
 * Project: http://code.google.com/p/ossecdb-extjs/
 *
 * License: http://www.gnu.org/licenses/gpl-3.0.html
 */

Ext.define('OssecWeb.view.alert.Grid', {

	extend: 'Ext.grid.Panel',

	alias: 'widget.alertgrid',

	requires: [
		'OssecWeb.lib.CountryCode', 
		'OssecWeb.lib.Inet', 
		'OssecWeb.lib.Level'
	],

	initComponent: function() {

		var filters = [{
				type: 'numeric',
				disabled: false,
				dataIndex: 'alert_id'
			},{
				type: 'string',
				disabled: true,
				dataIndex: 'user'
			},{
				type: 'numeric',
				disabled: false,
				dataIndex: 'rule_id'
			},{
				type: 'string',
				disabled: false,
				dataIndex: 'desc'
			},{
				type: 'string',
				disabled: true,
				dataIndex: 'loc_host'
			},{
				type: 'string',
				disabled: true,
				dataIndex: 'loc_path'
			},{
				type: 'string', 
				disabled: false, 
				dataIndex: 'src_ip'
			},{
				type: 'numeric', 
				disabled: false, 
				dataIndex: 'src_port'
			},{
				type: 'string', 
				disabled: false, 
				dataIndex: 'dst_ip'
			},{
				type: 'numeric', 
				disabled: false, 
				dataIndex: 'dst_port'
			},{
				type: 'string',
				disabled: false,
				dataIndex: 'full_log'
			},{
				type: 'date',
				dataIndex: 'time',
				dateFormat: 'Y-m-d'
			},
			this.getLevelFilter()
		];

		if (OssecWebConfig.geolocation.enabled) {
			filters.push(this.getCountryFilter('src'))
			filters.push(this.getCountryFilter('dst'))
		}

		var columns = [{
			text: 'Alert',
			columns: [{
					text: 'Alert ID',
					width: 50,
					sortable: true,
					dataIndex: 'alert_id',
					renderer: this.formatNumber
				},{
					text: 'Timestamp',
					width: 140,
					sortable: true,
					dataIndex: 'time',
					renderer: Ext.util.Format.dateRenderer(
						OssecWebConfig.format.dateFormat
					)
				},{
					text: 'User',
					width: 90,
					sortable: true,
					dataIndex: 'user',
					renderer: this.formatUser
				}]
			},{
				text: 'Signature',
				columns: [{
					text: 'Level',
					width: 50,
					sortable: true,
					dataIndex: 'level',
					renderer: this.formatLevel
				},{
					text: 'Level Description',
					width: 225,
					hidden: true,
					sortable: true,
					dataIndex: 'level',
					renderer: this.formatLevelDesc
				},{
					text: 'Rule ID',
					width: 50,
					hidden: true,
					sortable: true,
					dataIndex: 'rule_id',
					renderer: this.formatNumber
				},{
					text: 'Rule Description',
					width: 225,
					sortable: true,
					dataIndex: 'desc'
				}]
			},{
				text: 'Location',
				columns: [{
					text: 'Hostname',
					width: 90,
					sortable: true,
					dataIndex: 'loc_host'
				},{
					text: 'Process/Log',
					width: 130,
					sortable: true,
					dataIndex: 'loc_path'
				}]
			},{
				text: 'Source',
				columns: this.getLocationColumnModel('src')
			},{
				text: 'Destination',
				columns: this.getLocationColumnModel('dst')
			},{
				text: 'Full Log',
				width: 600,
				hidden: true,
				sortable: true,
				dataIndex: 'full_log'
			}];

		// ISSUE: temporary workaround
		for (var i = 0, h = 0; i < columns.length; i++) {
			columns[i].headerId = 'h' + (++h);
			if (columns[i].columns) {
				for (var j = 0; j < columns[i].columns.length; j++) {
					columns[i].columns[j].headerId = 'h' + (++h);
				}
			}
		}

		Ext.apply(this, {
			store: 'Alerts',
			loadMask: true,
			features: [{
				ftype: 'filters',
				local: false,
				encode: true,
				filters: filters
			}],
			columnLines: true,
			columns: columns
		});

		this.callParent(arguments);
	},

	getCountryFilter: function (prefix) {
		return {
			type: 'string', 
			dataIndex: prefix + '_cntry', 
			disabled: true
		};
	},

	getLevelFilter: function () {

		var filter = {
			type: 'list',
			single: true,
			dataIndex: 'level',
			labelField: 'label',
			options: []
		};

		for (var i = OssecWeb.lib.Level.levels.length - 1; i >= 0; i--) {

			var level = OssecWeb.lib.Level.levels[i];

			filter.options.push({
				id: i, label: '&ge; ' + level.level + ': ' + level.text
			});
		}

		return filter;
	},

	getLocationColumnModel: function (prefix) {

		var columns = [];

		if (OssecWebConfig.geolocation.enabled) {

			var renderer;

			if (OssecWebConfig.geolocation.countryCodes == 'ISO3166') {
				renderer = this.formatISO3166CountryCode;
			}

			columns.push({
				text: 'Geo',
				width: 31,
				sortable: true,
				dataIndex: prefix + '_cntry',
				renderer: renderer
			});
		}

		columns.push({
			text: 'IP Address',
			width: 107,
			sortable: true,
			dataIndex: prefix + '_ip',
			renderer: this.formatIpAddress
		},{
			text: 'Port',
			width: 60,
			sortable: true,
			dataIndex: prefix + '_port',
			renderer: this.formatNumber
		});

		return columns;
	},

	formatNumber: function (id) {
		return '<div class="number-cell">' + id + '</div>';
	},

	formatLevel: function (level) {
		level = OssecWeb.lib.Level.levels[level];
		return '<div class="center-cell"><span class="level level_' + level.level + ' level-cell" title="Level ' + level.level + ': ' + level.text + '">' + level.level + '</span></div>';
	},

	formatLevelDesc: function (level) {
		return OssecWeb.lib.Level.levels[level].text;
	},

	formatUser: function (value) {
		if (value == '(none)') {
			return '<span class="opaque">' + value + '</span>';
		}
		return value;
	},

	formatIpAddress: function (value) {
		if (value > 0) {
			return '<div class="ip-address-cell"><div class="ip-block">' + OssecWeb.lib.Inet.getNtoa(value, '</div><div class="ip-delim">.</div><div class="ip-block">') + '</div></div>';
		}
	},

	formatISO3166CountryCode: function (value) {
		if (value) {
			var title = OssecWeb.lib.CountryCode.ISO3166[value];
			if (title == null) {
				title = 'ISO3166: ' + value;
			}
			return '<div class="flag-cell"><img src="resources/famfamfam.com/flag/' + value.toLowerCase() + '.gif" title="' + title + '"></div>'
		}
	},

	// ISSUE: temporary workaround
    getState: function(){

		function iCreateStateHeader (header) {

			var column = {
				id: header.headerId
			};

			if (header.hidden !== (header.initialConfig.hidden || header.self.prototype.hidden)) {
                column.hidden = header.hidden;
			}

			if (header.sortable !== header.initialConfig.sortable) {
                column.sortable = header.sortable;
            }

			if (header.flex) {
                if (header.flex !== header.initialConfig.flex) {
                    column.flex = header.flex;
                }
            } else {
                if (header.width !== header.initialConfig.width) {
                    column.width = header.width;
                }
            }

			return column;
		}

        var state	= this.callParent();
		var sorter	= this.store.sorters.first();

        state.columns = [];

        for (var i = 0; i < this.headerCt.items.items.length; i++) {
			state.columns[i] = iCreateStateHeader(
				this.headerCt.items.items[i]
			);
			if (this.headerCt.items.items[i].items.items.length) {
				state.columns[i].columns = [];
				for (var j = 0; j < this.headerCt.items.items[i].items.items.length; j++) {
					state.columns[i].columns[j] = iCreateStateHeader(
						this.headerCt.items.items[i].items.items[j]
					);
				}
			}
        }

        if (sorter) {
            state.sort = {
                property: sorter.property,
                direction: sorter.direction
            };
        }

        return state;
    },

	// ISSUE: temporary workaround
    applyState: function(state) {

		function iApplyStateHeader (header, column) {

			if (Ext.isDefined(column.hidden)) {
				header.hidden = column.hidden;
			}

			if (Ext.isDefined(column.sortable)) {
				header.sortable = column.sortable;
			}

			if (Ext.isDefined(column.flex)) {
				delete header.width;
				header.flex = column.flex;
			} else if (Ext.isDefined(column.width)) {
				delete header.flex;
				header.minWidth = column.width;
				if (header.rendered) {
					header.setWidth(column.width);
				} else {
					header.width = column.width;
				}
			}
		}

        this.headerCt.suspendLayout = true;

		// this.callParent(arguments);

		for (var i = 0; i < state.columns.length ; i++) {

			var column = state.columns[i];

			var header = this.headerCt.down(
				'gridcolumn[headerId=' + column.id + ']'
			);

			var index = this.headerCt.items.indexOf(header);

			if (i !== index) {
				this.headerCt.moveHeader(index, i);
			}

			iApplyStateHeader(header, column);

			if (column.columns) {

				for (var j = 0; j < column.columns.length; j++) {

					var subColumn = column.columns[j];

					var subHeader = this.headerCt.down(
						'gridcolumn[headerId=' + subColumn.id + ']'
					);

					var subIndex = header.items.indexOf(subHeader);

					if (j !== subIndex) {
						header.move(subIndex, j); // header.moveHeader(subIndex, j);
					}

					iApplyStateHeader(subHeader, subColumn);
				}
			}

		}

		this.headerCt.suspendLayout = false;
        this.headerCt.doLayout();

		if (state.sort) {
			if (this.store.remoteSort) {
				this.store.sorters.add(Ext.create('Ext.util.Sorter', {
					property: state.sort.property,
					direction: state.sort.direction
				}));
			} else {
				this.store.sort(
					state.sort.property, 
					state.sort.direction
				);
			}
		}
	}
});